/**
 * @description 请求拦截器
 * @param {Object} http 请求配置
 * @return {Object} 请求配置
 */
const requestInterceptor = (http) => {
  // 添加token等请求头信息
  const token = uni.getStorageSync('token');
  if (token) {
    http.header = {
      ...http.header,
      'Authorization': `Bearer ${token}`
    };
  }
  return http;
};

/**
 * @description 响应拦截器
 * @param {Object} response 响应结果
 * @return {Object|Promise} 响应结果或错误对象
 */
const responseInterceptor = (response) => {
  // 这里可以根据后端接口规范自定义
  const { statusCode, data } = response;
  
  // 请求成功
  if (statusCode >= 200 && statusCode < 300) {
    // 根据业务状态码判断请求是否成功
    if (data.code === 0 || data.code === 200) {
      return data;
    } else {
      // 业务错误处理
      const error = new Error(data.message || '请求失败');
      error.code = data.code;
      uni.showToast({
        title: data.message || '请求失败',
        icon: 'none',
        duration: 2000
      });
      return Promise.reject(error);
    }
  } else {
    // HTTP错误处理
    let message = '';
    
    switch (statusCode) {
      case 401:
        message = '未授权，请重新登录';
        // 可以在这里处理登录过期的逻辑
        uni.removeStorageSync('token');
        // 跳转到登录页
        setTimeout(() => {
          uni.navigateTo({
            url: '/pages/login/login'
          });
        }, 1500);
        break;
        
      case 403:
        message = '拒绝访问';
        break;
        
      case 404:
        message = '请求错误，未找到该资源';
        break;
        
      case 500:
        message = '服务器端出错';
        break;
        
      default:
        message = `连接错误${statusCode}`;
    }
    
    uni.showToast({
      title: message,
      icon: 'none',
      duration: 2000
    });
    
    const error = new Error(message);
    error.code = statusCode;
    return Promise.reject(error);
  }
};

/**
 * @description 发起请求
 * @param {Object} options 请求配置
 * @return {Promise} 请求结果
 */
const request = (options) => {
  // 请求拦截
  const http = requestInterceptor(options);
  
  // 发起请求
  return new Promise((resolve, reject) => {
    uni.request({
      ...http,
      success: (response) => {
        try {
          const result = responseInterceptor(response);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      },
      fail: (error) => {
        uni.showToast({
          title: '网络异常，请检查网络设置',
          icon: 'none',
          duration: 2000
        });
        reject(error);
      }
    });
  });
};

/**
 * @description 请求方法封装
 */
const http = {
  /**
   * GET请求
   * @param {String} url 请求地址
   * @param {Object} params 请求参数
   * @param {Object} options 其他配置
   * @return {Promise} 请求结果
   */
  get: (url, params = {}, options = {}) => {
    return request({
      url,
      method: 'GET',
      data: params,
      ...options
    });
  },
  
  /**
   * POST请求
   * @param {String} url 请求地址
   * @param {Object} data 请求数据
   * @param {Object} options 其他配置
   * @return {Promise} 请求结果
   */
  post: (url, data = {}, options = {}) => {
    return request({
      url,
      method: 'POST',
      data,
      ...options
    });
  },
  
  /**
   * PUT请求
   * @param {String} url 请求地址
   * @param {Object} data 请求数据
   * @param {Object} options 其他配置
   * @return {Promise} 请求结果
   */
  put: (url, data = {}, options = {}) => {
    return request({
      url,
      method: 'PUT',
      data,
      ...options
    });
  },
  
  /**
   * DELETE请求
   * @param {String} url 请求地址
   * @param {Object} data 请求数据
   * @param {Object} options 其他配置
   * @return {Promise} 请求结果
   */
  delete: (url, data = {}, options = {}) => {
    return request({
      url,
      method: 'DELETE',
      data,
      ...options
    });
  },
  
  /**
   * 上传文件
   * @param {String} url 上传地址
   * @param {Object} options 上传配置
   * @return {Promise} 上传结果
   */
  upload: (url, options = {}) => {
    const { filePath, name = 'file', formData = {}, ...rest } = options;
    
    // 请求拦截
    const http = requestInterceptor({ url, header: rest.header || {} });
    
    return new Promise((resolve, reject) => {
      uni.uploadFile({
        url,
        filePath,
        name,
        formData,
        header: http.header,
        ...rest,
        success: (response) => {
          try {
            // 上传接口可能返回的是字符串
            if (typeof response.data === 'string') {
              response.data = JSON.parse(response.data);
            }
            const result = responseInterceptor(response);
            resolve(result);
          } catch (error) {
            reject(error);
          }
        },
        fail: (error) => {
          uni.showToast({
            title: '上传失败，请重试',
            icon: 'none',
            duration: 2000
          });
          reject(error);
        }
      });
    });
  },
  
  /**
   * 下载文件
   * @param {String} url 下载地址
   * @param {Object} options 下载配置
   * @return {Promise} 下载结果
   */
  download: (url, options = {}) => {
    // 请求拦截
    const http = requestInterceptor({ url, header: options.header || {} });
    
    return new Promise((resolve, reject) => {
      uni.downloadFile({
        url,
        header: http.header,
        ...options,
        success: (response) => {
          // 下载成功仅返回临时路径
          if (response.statusCode === 200) {
            resolve(response.tempFilePath);
          } else {
            const error = new Error('下载失败');
            error.code = response.statusCode;
            reject(error);
          }
        },
        fail: (error) => {
          uni.showToast({
            title: '下载失败，请重试',
            icon: 'none',
            duration: 2000
          });
          reject(error);
        }
      });
    });
  }
};

export default http; 